// TransfersServer.cpp : �������̨Ӧ�ó������ڵ㡣
//
#include <tchar.h>
#include <WinSock2.h>
#include <Windows.h>
#include <vector>
#include <set>
#include <map>
#include "Lock.h"
#include "ServiceWin32.h"
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define TRANSSERVER "119.28.16.61"
//#define TRANSSERVER "192.168.1.17"
extern TCHAR serviceLongName[100] = _T("NutBrowser");
extern TCHAR serviceName[100] = _T("NutBrowser");
extern TCHAR serviceDescription[100] = _T("");
extern int m_ServiceStatus;
CLock g_lock;
set<ULONG> g_addrset;
SOCKET g_socket;
map<SOCKET, SOCKET> g_sockpair;
DWORD WINAPI LocalSendToThread(LPVOID lparam);
DWORD WINAPI RequestThread(LPVOID lparam);
DWORD WINAPI ProcessThread(LPVOID lparam);
DWORD WINAPI ConnectThread(LPVOID lparam);
DWORD WINAPI LocalRecvFromThread(LPVOID lparam);
DWORD WINAPI ListenThread(LPVOID lparam);
bool ConnectTransServer(char* ipstr);
void hexprint(char *buf, int len);
bool isip(char* str);
bool SendLenData(SOCKET socket, char* buf, int len);
bool GetLenData(SOCKET socket, char* buf, int len);
bool SingleSend(SOCKET clientsocket, char* buf, unsigned short slen);
int _tmain(int argc, _TCHAR* argv[])
{
	printf("%d", argc);
	int c = 1;
	while (c < argc)
	{
		if (_tcscmp(argv[c], _T("-s")) == 0) // Services
		{
			if (++c >= argc)
			{
				printf("Runtime-Error: -s option requires an input argument");
				return 1;
			}

			if (_tcscmp(argv[c], _T("install")) == 0)
			{
				if (WinServiceUninstall())
					printf("Uninstalling service\n");
				if (WinServiceInstall())
					printf("Installing service\n");
				return 1;
			}
			else if (_tcscmp(argv[c], _T("uninstall")) == 0)
			{
				if (WinServiceUninstall())
					printf("Uninstalling service\n");
				return 1;
			}
			else
			{
				printf("Runtime-Error: unsupported option %s", argv[c]);
				return 1;
			}
		}

		if (_tcscmp(argv[c], _T("--service")) == 0)
			WinServiceRun();
		++c;
	}
	WSADATA wsaData;
	int err;
	err = WSAStartup(MAKEWORD(2, 2), &wsaData);
	sockaddr_in local;
	local.sin_family = AF_INET;
	local.sin_port = htons(5020);
	local.sin_addr.S_un.S_addr = INADDR_ANY;
	SOCKET listensocket = socket(AF_INET, SOCK_STREAM, 0);
	g_socket = socket(AF_INET, SOCK_STREAM, 0);
	//int breuseaddr=1;
	//setsockopt(listensocket,SOL_SOCKET,SO_REUSEADDR,(const char*)&breuseaddr,sizeof(int));
	//int nNetTimeout=1000;//1��
	//����ʱ��
	//setsockopt(listensocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
	//����ʱ��
	//setsockopt(listensocket,SOL_SOCKET,SO_RCVTIMEO,(char *)&nNetTimeout,sizeof(int));
	if (bind(listensocket, (LPSOCKADDR)&local, sizeof(local)) == SOCKET_ERROR)
	{
		printf("�󶨶˿�ʧ��\r\n");
		closesocket(listensocket);
		return false;
	}
	if (listen(listensocket, 1000) == SOCKET_ERROR)
	{
		printf("listen error");
		return 0;
	}
	printf("start server success\r\n");
	HANDLE h = CreateThread(NULL, 0, ListenThread, (LPVOID)listensocket, 0, NULL);
	CloseHandle(h);
	if (ConnectTransServer(TRANSSERVER))
	{
		printf("������ת�������ɹ���\r\n");
		h = CreateThread(NULL, 0, RequestThread, NULL, 0, NULL);
		CloseHandle(h);
	}
	while (m_ServiceStatus)
	{
		Sleep(1000);
	}
	return 0;
}
struct SOCKETPAIR{
	SOCKET clientsocket;
	SOCKET remotesocket;
};
bool ConnectTransServer(char* ipstr)
{
	bool ret = false;
	g_socket = socket(AF_INET, SOCK_STREAM, 0);
	struct sockaddr_in remoteaddr;
	remoteaddr.sin_family = AF_INET;
	remoteaddr.sin_port = htons(5021);
	remoteaddr.sin_addr.S_un.S_addr = inet_addr(ipstr);
	if (connect(g_socket, (sockaddr*)&remoteaddr, sizeof(sockaddr_in)) < 0)
	{
		printf("������ת������ʧ�ܣ�error %d\r\n",GetLastError());
	}
	ret = true;
	return ret;
}
DWORD WINAPI ListenThread(LPVOID lparam)
{
	SOCKET listensocket = (SOCKET)lparam;
	while (1)
	{
		SOCKET clientsocket;
		sockaddr_in clientaddr;
		int nlen = sizeof(sockaddr);
		clientsocket = accept(listensocket, (sockaddr*)&clientaddr, &nlen);
		printf("new client\r\n");
		struct sockaddr_in guestaddr;
		int addrlen = sizeof(guestaddr);
		getpeername(clientsocket, (struct sockaddr*)&guestaddr, &addrlen);
		if (guestaddr.sin_addr.S_un.S_un_b.s_b1 == 0x7f)
		{
			HANDLE h = CreateThread(NULL, 0, LocalSendToThread, (LPVOID)clientsocket, 0, NULL);
			CloseHandle(h);
		}
		else
		{
			HANDLE h = CreateThread(NULL, 0, ProcessThread, (LPVOID)clientsocket, 0, NULL);
			CloseHandle(h);
		}
		//printf("��������ip %s\r\n",inet_ntoa(guestaddr.sin_addr));
		//�ж��Ƿ��Ǳ������ӣ������ ����������̣߳�������ǣ����ⲿ�����߳�
		//struct linger so_linger;
		// so_linger.l_onoff  = 1;
		//so_linger.l_linger = 30;
		// setsockopt(clientsocket ,SOL_SOCKET, SO_LINGER, (const char*)&so_linger, sizeof(so_linger));
	}
}
bool SendLenData(SOCKET socket, char* buf, int len)
{
	bool ret = false;
	int slen = 0;
	int alllen = 0;
	while (alllen < len)
	{
		slen = send(socket, buf + alllen, len - alllen, 0);
		if (slen > 0)
		{
			alllen += slen;
			if (alllen == len)
			{
				ret = true;
				break;
			}
		}
		else
		{
			printf("send error %d \r\n",GetLastError());
			break;
		}
	}
	return ret;
}
bool GetLenData(SOCKET socket, char* buf, int len)
{
	bool ret = false;
	int rlen = 0;
	int alllen = 0;
	while (alllen < len)
	{
		rlen = recv(socket, buf + alllen, len - alllen, 0);
		if (rlen > 0)
		{
			alllen += rlen;
			if (alllen == len)
			{
				ret = true;
				break;
			}
		}
		else
		{
			break;
		}
	}

	return ret;
}
struct ConnectInfo{
	SOCKET lsocket;
	SOCKET clientsocket;
	sockaddr_in remoteaddr;
	unsigned short len;
	char httphead[64 * 1024];
};
DWORD WINAPI RequestThread(LPVOID lparam)
{
	char buf[64 * 1024] = { 0 };
	int len = 64 * 1024;
	unsigned short packetlen = 0;
	while (1)
	{
		if (!GetLenData(g_socket, (char*)&packetlen, sizeof(packetlen)))
		{
			break;
		}
		if (!GetLenData(g_socket, buf, packetlen))
		{
			break;
		}
		char action = buf[0];
		SOCKET lsocket, rsocket;
		lsocket = *((SOCKET*)&buf[sizeof(char)]);
		rsocket = *((SOCKET*)&buf[sizeof(char) + sizeof(SOCKET)]);
		char databuf[64 * 1024] = { 0 };
		unsigned short datalen = 0;
		datalen = *((unsigned short*)&buf[sizeof(char) + 2 * sizeof(SOCKET)]);
		memcpy(databuf, buf + sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short), datalen);
		if (action == 4)
		{
			closesocket(lsocket);
		}
		else if (action == 5)
		{
			printf("�ܵ�����ת���������ص� ����\r\n%s\r\n", databuf);
			g_sockpair[lsocket] = rsocket;
			SendLenData(lsocket, databuf, datalen);
		}
		else
		{
			_asm int 3;
		}
	}
	closesocket(g_socket);
	return 0;
}
//Э�� ������ ���� ����socket Զ��socket ���ݳ��� ����
//����  1,�������� 2,����ͷ 3���Ͽ����� 4����ͻ��˶Ͽ�����  5�������ݷ���
DWORD WINAPI ProcessThread(LPVOID lparam)
{
	SOCKET clientsocket = (SOCKET)lparam;
	unsigned short packetlen = 0;
	int rlen = 0;
	char buf[64 * 1024] = { 0 };
	while (1)
	{
		if (!GetLenData(clientsocket, (char*)&packetlen, sizeof(packetlen)))
		{
			break;
		}
		if (!GetLenData(clientsocket, buf, packetlen))
		{
			break;
		}
		char action = buf[0];
		SOCKET lsocket, rsocket;
		lsocket = *((SOCKET*)&buf[sizeof(char)]);
		rsocket = *((SOCKET*)&buf[sizeof(char) + sizeof(SOCKET)]);
		char databuf[64 * 1024];
		unsigned short datalen = 0;
		datalen = *((unsigned short*)&buf[sizeof(char) + 2 * sizeof(SOCKET)]);
		memcpy(databuf, buf + sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short), datalen);
		if (action == 1)
		{
			struct ConnectInfo* pinfo = new ConnectInfo;
			pinfo->lsocket = lsocket;
			pinfo->clientsocket = clientsocket;
			memcpy(&pinfo->remoteaddr, databuf, sizeof(sockaddr_in));
			memset(pinfo->httphead, 0, 64 * 1024);
			memcpy(pinfo->httphead, databuf + sizeof(sockaddr_in), datalen - sizeof(sockaddr_in));
			pinfo->len = datalen - sizeof(sockaddr_in);
			HANDLE h = CreateThread(NULL, 0, ConnectThread, (LPVOID)pinfo, 0, NULL);
			CloseHandle(h);

		}
		else if (action == 2)
		{
			SendLenData(rsocket, databuf, datalen);
		}
		else if (action == 3)
		{
			closesocket(rsocket);
		}
		else
		{
			_asm int 3;
		}
	}
	closesocket(clientsocket);
	return 0;
}
bool SingleSend(SOCKET clientsocket, char* buf, unsigned short slen)
{
	bool ret = true;
	g_lock.Lock();
	if (slen == 0)
	{
		_asm int 3;
	}
	if (!SendLenData(clientsocket, (char*)&slen, sizeof(unsigned short)))
	{
		ret = false;
	}
	else
	{
		if (!SendLenData(clientsocket, buf, slen))
		{
			ret = false;
		}
	}
	if (!ret)
	{
		if (ConnectTransServer(TRANSSERVER))
		{
			printf("������ת�������ɹ���\r\n");
			HANDLE h = CreateThread(NULL, 0, RequestThread, NULL, 0, NULL);
			CloseHandle(h);
			ret = true;
			if (!SendLenData(clientsocket, (char*)&slen, sizeof(unsigned short)))
			{
				ret = false;
			}
			else
			{
				if (!SendLenData(clientsocket, buf, slen))
				{
					ret = false;
				}
			}
		}
	}
	g_lock.UnLock();

	return ret;
}
DWORD WINAPI ConnectThread(LPVOID lparam)
{
	struct ConnectInfo* pinfo = (struct ConnectInfo*)lparam;
	char buf[64 * 1024] = { 0 };
	char sendbuf[64 * 1024] = { 0 };
	int len = 64 * 1024 - 200;
	int sendlen = 0;
	unsigned short slen = 0;
	SOCKET remotesocket = socket(AF_INET, SOCK_STREAM, 0);
	char url[1024] = { 0 };
	printf("����ͷ���� Ϊ %s\r\n", pinfo->httphead);
	if (pinfo->httphead[0] == 0x16)
	{
		int strpos = -1;
		for (int i = 0; i < pinfo->len - 4; i++)
		{
			if (pinfo->httphead[i] == '.' && pinfo->httphead[i + 1] == 'c' && pinfo->httphead[i + 2] == 'o' && pinfo->httphead[i + 3] == 'm')
			{
				strpos = i;
				break;
			}
			if (pinfo->httphead[i] == '.' && pinfo->httphead[i + 1] == 'c' && pinfo->httphead[i + 2] == 'n')
			{
				strpos = i;
				break;
			}
			if (pinfo->httphead[i] == '.' && pinfo->httphead[i + 1] == 'o' && pinfo->httphead[i + 2] == 'r' && pinfo->httphead[i + 3] == 'g')
			{
				strpos = i;
				break;
			}
			if (pinfo->httphead[i] == '.' && pinfo->httphead[i + 1] == 'n' && pinfo->httphead[i + 2] == 'e' && pinfo->httphead[i + 3] == 't')
			{
				strpos = i;
				break;
			}
			if (pinfo->httphead[i] == '.' && pinfo->httphead[i + 1] == 'j' && pinfo->httphead[i + 2] == 'p')
			{
				strpos = i;
				break;
			}
			if (pinfo->httphead[i] == '.' && pinfo->httphead[i + 1] == 'd' && pinfo->httphead[i + 2] == 'e')
			{
				strpos = i;
				break;
			}
		}
		if (strpos > 0)
		{
			while (strpos>0)
			{
				if (pinfo->httphead[strpos] >= 'a' && pinfo->httphead[strpos] <= 'z')
				{
					strpos--;
				}
				else if (pinfo->httphead[strpos] == '.')
				{
					strpos--;
				}
				else if (pinfo->httphead[strpos] == '-')
				{
					strpos--;
				}
				else if (pinfo->httphead[strpos] >= '0' && pinfo->httphead[strpos] <= '9')
				{
					strpos--;
				}
				else
					break;
			}

			if (strpos > 0)
			{
				strpos++;
			}
		}

		int endpos = strpos;
		while (endpos<pinfo->len)
		{
			if (pinfo->httphead[endpos] == 0x00 || pinfo->httphead[endpos] == 0x0d || pinfo->httphead[endpos] == 0x0a || pinfo->httphead[endpos] == '/' || pinfo->httphead[endpos] == '%')
			{
				break;
			}
			endpos++;
		}
		memcpy(url, pinfo->httphead + strpos, endpos - strpos);
	}
	else
	{
		int strpos = -1;
		for (int i = 0; i < pinfo->len - 4; i++)
		{
			if (pinfo->httphead[i] == 'H' && pinfo->httphead[i + 1] == 'o' && pinfo->httphead[i + 2] == 's' && pinfo->httphead[i + 3] == 't')
			{
				strpos = i;
				break;
			}
		}
		if (strpos > 0)
		{
			strpos += 6;
		}
		int endpos = strpos;
		while (endpos < pinfo->len)
		{
			if (pinfo->httphead[endpos] == 0x0d || pinfo->httphead[endpos] == ':')
			{
				break;
			}
			endpos++;
		}
		if ((endpos - strpos) <= 1000)
		{
			memcpy(url, pinfo->httphead + strpos, endpos - strpos);
		}
	}
	printf("Ҫ���ӵ������� %s\r\n", url);
	if (strlen(url) == 0)
	{
		//MessageBox(NULL, _T("�����޷�����"), _T("�����޷�����"), MB_OK);
		if (connect(remotesocket, (sockaddr*)&pinfo->remoteaddr, sizeof(sockaddr_in)) < 0)
		{
			//֪ͨ ����ʧ��
			sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + 0;
			sendbuf[0] = 4;
			*(SOCKET*)&sendbuf[sizeof(char)] = pinfo->lsocket;
			*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = remotesocket;
			*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
			slen = sendlen;
			SingleSend(pinfo->clientsocket, sendbuf, slen);
			//send(pinfo->clientsocket, (char*)&slen, sizeof(unsigned short), 0);
			//send(pinfo->clientsocket, sendbuf, slen, 0);
			closesocket(remotesocket);
			goto outthread;
			return 0;
		}
		if (send(remotesocket, pinfo->httphead, pinfo->len, 0) < 0)
		{
			//֪ͨ����ʧ��
			sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + 0;
			sendbuf[0] = 4;
			*(SOCKET*)&sendbuf[sizeof(char)] = pinfo->lsocket;
			*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = remotesocket;
			*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
			slen = sendlen;
			SingleSend(pinfo->clientsocket, sendbuf, slen);
			//send(pinfo->clientsocket, (char*)&slen, sizeof(unsigned short), 0);
			//send(pinfo->clientsocket, sendbuf, slen, 0);
			closesocket(remotesocket);
			goto outthread;
			return 0;
		}
	}
	else
	{
		if (isip(url))
		{
			pinfo->remoteaddr.sin_addr.S_un.S_addr = inet_addr(url);
			if (connect(remotesocket, (sockaddr*)&pinfo->remoteaddr, sizeof(sockaddr_in)) < 0)
			{
				//֪ͨ����ʧ��
				sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + 0;
				sendbuf[0] = 4;
				*(SOCKET*)&sendbuf[sizeof(char)] = pinfo->lsocket;
				*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = remotesocket;
				*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
				slen = sendlen;
				SingleSend(pinfo->clientsocket, sendbuf, slen);
				//send(pinfo->clientsocket, (char*)&slen, sizeof(unsigned short), 0);
				//send(pinfo->clientsocket, sendbuf, slen, 0);
				closesocket(remotesocket);
				goto outthread;
				return 0;
			}
			if (send(remotesocket, pinfo->httphead, pinfo->len, 0) < 0)
			{
				//֪ͨ����ʧ��
				sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + 0;
				sendbuf[0] = 4;
				*(SOCKET*)&sendbuf[sizeof(char)] = pinfo->lsocket;
				*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = remotesocket;
				*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
				slen = sendlen;
				SingleSend(pinfo->clientsocket, sendbuf, slen);
				//send(pinfo->clientsocket, (char*)&slen, sizeof(unsigned short), 0);
				//send(pinfo->clientsocket, sendbuf, slen, 0);
				closesocket(remotesocket);
				goto outthread;
				return 0;
			}
		}
		else
		{
			hostent *phst = gethostbyname(url);
			if (phst)
			{
				pinfo->remoteaddr.sin_addr = *(in_addr*)phst->h_addr;
				//printf("socket %d Զ��ip:%s port:%d\r\n", clientsocket, inet_ntoa(remoteaddr.sin_addr), ntohs(remoteaddr.sin_port));
				if (connect(remotesocket, (sockaddr*)&pinfo->remoteaddr, sizeof(sockaddr_in)) < 0)
				{
					unsigned short port = ntohs(pinfo->remoteaddr.sin_port);
					//printf("socket %d Զ��ip:%s port:%d\r\n", clientsocket, inet_ntoa(remoteaddr.sin_addr), ntohs(remoteaddr.sin_port));
					//printf("socket %d %s\r\n", clientsocket, sendbuf);
					//printf("socket %d connect error error code:%d\r\n", clientsocket, GetLastError());
					//closesocket(clientsocket);
					//֪ͨ����ʧ��
					sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + 0;
					sendbuf[0] = 4;
					*(SOCKET*)&sendbuf[sizeof(char)] = pinfo->lsocket;
					*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = remotesocket;
					*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
					slen = sendlen;
					SingleSend(pinfo->clientsocket, sendbuf, slen);
					//send(pinfo->clientsocket, (char*)&slen, sizeof(unsigned short), 0);
					//send(pinfo->clientsocket, sendbuf, slen, 0);
					closesocket(remotesocket);
					goto outthread;
					return 0;
				}
				if (send(remotesocket, pinfo->httphead, pinfo->len, 0) < 0)
				{
					//closesocket(clientsocket);
					//֪ͨ����ʧ��
					sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + 0;
					sendbuf[0] = 4;
					*(SOCKET*)&sendbuf[sizeof(char)] = pinfo->lsocket;
					*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = remotesocket;
					*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
					slen = sendlen;
					SingleSend(pinfo->clientsocket, sendbuf, slen);
					//send(pinfo->clientsocket, (char*)&slen, sizeof(unsigned short), 0);
					//send(pinfo->clientsocket, sendbuf, slen, 0);
					closesocket(remotesocket);
					goto outthread;
					return 0;
				}
			}
			else
			{
				//֪ͨ����ʧ��
				//Э�� ������ ���� ����socket Զ��socket ���ݳ��� ����
				//����  1,�������� 2,����ͷ 3���Ͽ����� 4����ͻ��˶Ͽ�����  5�������ݷ���
				sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + 0;
				sendbuf[0] = 4;
				*(SOCKET*)&sendbuf[sizeof(char)] = pinfo->lsocket;
				*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = remotesocket;
				*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
				slen = sendlen;
				SingleSend(pinfo->clientsocket, sendbuf, slen);
				//send(pinfo->clientsocket, (char*)&slen, sizeof(unsigned short), 0);
				//send(pinfo->clientsocket, sendbuf, slen, 0);
				closesocket(remotesocket);
				goto outthread;
				return 0;
			}
		}
	}
	printf("���ӳɹ�\r\n");
	while (1)
	{
		int rlen = 0;
		rlen = recv(remotesocket, buf, len, 0);
		if (rlen <= 0)
		{
			printf("socket %d ��������Ͽ����� error %d\r\n", remotesocket, GetLastError());
			sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + 0;
			sendbuf[0] = 4;
			*(SOCKET*)&sendbuf[sizeof(char)] = pinfo->lsocket;
			*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = remotesocket;
			*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
			slen = sendlen;
			SingleSend(pinfo->clientsocket, sendbuf, slen);
			break;
		}
		else
		{
			printf("�յ���վ�������������� \r\n");
			printf("%s\r\n",buf);
			//Э�� ������ ���� ����socket Զ��socket ���ݳ��� ����
			//����  1,�������� 2,����ͷ 3���Ͽ����� 4����ͻ��˶Ͽ�����  5�������ݷ���
			sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + rlen;
			sendbuf[0] = 5;
			*(SOCKET*)&sendbuf[sizeof(char)] = pinfo->lsocket;
			*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = remotesocket;
			*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = rlen;
			memcpy(sendbuf + sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short), buf, rlen);
			unsigned short slen = sendlen;
			SingleSend(pinfo->clientsocket, sendbuf, slen);

			//if (send(pinfo->clientsocket, (char*)&slen, sizeof(unsigned short), 0) < 0)
			//	break;
			//if (send(pinfo->clientsocket, sendbuf, slen, 0) < 0)
			//	break;
		}
	}
	outthread:
	closesocket(remotesocket);
	delete pinfo;
	return 0;
}
DWORD WINAPI LocalRecvFromThread(LPVOID lparam)
{
	SOCKETPAIR* param = (SOCKETPAIR*)lparam;
	SOCKET clientsocket = param->clientsocket;
	SOCKET remotesocket = param->remotesocket;
	int len = 64 * 1024;
	char sendbuf[64 * 1024] = { 0 };
	while (1)
	{
		int rlen = 0;
		rlen = recv(remotesocket, sendbuf, len, 0);
		printf("Զ�̷�������������: len=%d\r\n", rlen);
		//printf("Զ�̷���������\r\n%s\r\n",sendbuf);
		if (rlen <= 0)
		{
			printf("��Զ�̷������Ͽ����� error %d\r\n", GetLastError());
			break;
		}
		else
		{
			if (send(clientsocket, sendbuf, rlen, 0) < 0)
				break;
		}

	}
	closesocket(remotesocket);
	closesocket(clientsocket);
	delete param;
	return 0;
}
DWORD WINAPI LocalSendToThread(LPVOID lparam)
{
	SOCKET clientsocket = (SOCKET)lparam;
	int len = 64 * 1024;
	char sendbuf[64 * 1024] = { 0 };
	sockaddr_in remoteaddr;
	int rl = recv(clientsocket, (char*)&remoteaddr, sizeof(sockaddr_in), 0);
	if (rl > 0 && rl < sizeof(sockaddr_in))
	{
		recv(clientsocket, ((char*)&remoteaddr) + rl, sizeof(sockaddr_in) - rl, 0);
	}
	unsigned short port = ntohs(remoteaddr.sin_port);
	SOCKET remotesocket = socket(AF_INET, SOCK_STREAM, 0);
	if (g_addrset.find(remoteaddr.sin_addr.S_un.S_addr) == g_addrset.end())
	{
		if (connect(remotesocket, (sockaddr*)&remoteaddr, sizeof(sockaddr_in)) < 0)
		{
			g_addrset.insert(remoteaddr.sin_addr.S_un.S_addr);
			printf("ֱ�����ӷ�����ʧ�ܣ���ʼ������ת��������\r\n");
			char buf[64 * 1024] = { 0 };
			int len = 64 * 1024;
			int rlen = recv(clientsocket, buf, len, 0);
			if (rlen <= 0)
			{
				closesocket(clientsocket);
				return 0;
			}

			int sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + sizeof(struct sockaddr_in) + rlen;
			sendbuf[0] = 1;
			*(SOCKET*)&sendbuf[sizeof(char)] = clientsocket;
			*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = INVALID_SOCKET;
			*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = rlen + sizeof(struct sockaddr_in);
			memcpy(sendbuf + sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short), &remoteaddr, sizeof(struct sockaddr_in));
			memcpy(sendbuf + sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + sizeof(struct sockaddr_in), buf, rlen);
			unsigned short slen = sendlen;
			SingleSend(g_socket, sendbuf, slen);
			while (1)
			{
				int rlen = 0;
				rlen = recv(clientsocket, buf, len, 0);
				if (rlen <= 0)
				{
					printf("socket %d ��ͻ��˶Ͽ����� error %d\r\n", clientsocket, GetLastError());
					sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short);
					sendbuf[0] = 3;
					*(SOCKET*)&sendbuf[sizeof(char)] = clientsocket;
					*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = g_sockpair[clientsocket];
					*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
					unsigned short slen = sendlen;
					SingleSend(g_socket, sendbuf, slen);
					break;
				}
				else
				{
					sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + rlen;
					sendbuf[0] = 2;
					*(SOCKET*)&sendbuf[sizeof(char)] = clientsocket;
					*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = g_sockpair[clientsocket];
					*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = rlen;
					memcpy(sendbuf + sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short), buf, rlen);
					unsigned short slen = sendlen;
					SingleSend(g_socket, sendbuf, slen);
				}
			}
			closesocket(clientsocket);
			return 0;
		}
	}
	else
	{
		printf("�ϴ�����ʧ�ܹ���ֱ��������ת��������\r\n");

		char buf[64 * 1024] = { 0 };
		int len = 64 * 1024;
		int rlen = recv(clientsocket, buf, len, 0);
		if (rlen <= 0)
		{
			closesocket(clientsocket);
			return 0;
		}
			
		int sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + sizeof(struct sockaddr_in) + rlen;
		sendbuf[0] = 1;
		*(SOCKET*)&sendbuf[sizeof(char)] = clientsocket;
		*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = INVALID_SOCKET;
		*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = rlen + sizeof(struct sockaddr_in);
		memcpy(sendbuf + sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short), &remoteaddr, sizeof(struct sockaddr_in));
		memcpy(sendbuf + sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + sizeof(struct sockaddr_in), buf, rlen);
		unsigned short slen = sendlen;
		SingleSend(g_socket, sendbuf, slen);
		while (1)
		{
			int rlen = 0;
			rlen = recv(clientsocket, buf, len, 0);
			if (rlen <= 0)
			{
				printf("socket %d ��ͻ��˶Ͽ����� error %d\r\n", clientsocket, GetLastError());
				sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short);
				sendbuf[0] = 3;
				*(SOCKET*)&sendbuf[sizeof(char)] = clientsocket;
				*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = g_sockpair[clientsocket];
				*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = 0;
				unsigned short slen = sendlen;
				SingleSend(g_socket, sendbuf, slen);
				break;
			}
			else
			{
				sendlen = sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short) + rlen;
				sendbuf[0] = 2;
				*(SOCKET*)&sendbuf[sizeof(char)] = clientsocket;
				*(SOCKET*)&sendbuf[sizeof(char) + sizeof(SOCKET)] = g_sockpair[clientsocket];
				*(unsigned short*)&sendbuf[sizeof(char) + 2 * sizeof(SOCKET)] = rlen;
				memcpy(sendbuf + sizeof(char) + 2 * sizeof(SOCKET) + sizeof(unsigned short), buf, rlen);
				unsigned short slen = sendlen;
				SingleSend(g_socket, sendbuf, slen);
			}
		}
		closesocket(clientsocket);
		return 0;
		/*struct sockaddr_in local;
		local.sin_family = AF_INET;
		local.sin_port = htons(5020);
		local.sin_addr.S_un.S_addr = inet_addr("119.28.16.61");
		g_lock.Lock();
		if (connect(remotesocket, (sockaddr*)&local, sizeof(sockaddr_in)) < 0)
		{
		g_lock.UnLock();
		return 0;
		}
		g_lock.UnLock();
		printf("socket %d ���ӳɹ�\r\n", clientsocket);
		send(remotesocket, (char*)&remoteaddr, sizeof(sockaddr_in), 0);*/
	}

	SOCKETPAIR* pparam = new SOCKETPAIR;
	pparam->clientsocket = clientsocket;
	pparam->remotesocket = remotesocket;
	HANDLE h = CreateThread(NULL, 0, LocalRecvFromThread, (LPVOID)pparam, 0, NULL);
	CloseHandle(h);
	while (1)
	{
		int rlen = 0;
		rlen = recv(clientsocket, sendbuf, len, 0);
		if (rlen <= 0)
		{
			printf("socket %d ��ͻ��˶Ͽ����� error %d\r\n", clientsocket, GetLastError());
			break;
		}
		else
		{
			if (send(remotesocket, sendbuf, rlen, 0) < 0)
				break;
		}

	}
	closesocket(clientsocket);
	closesocket(remotesocket);
	return 0;
}

void hexprint(char *buf, int len)
{
	int i;
	for (i = 0; i<len; i++)
	{
		printf("%02x ", (unsigned char)(buf[i]));
		if ((i + 1) % 16 == 0)
			printf("\r\n");
	}
	printf("\r\n");
}
bool isip(char* str)
{
	bool ret = true;
	int len = strlen(str);
	for (int i = 0; i < len; i++)
	{
		if (str[i] >= '0' && str[i] <= '9')
		{

		}
		else if (str[i] == '.')
		{
		}
		else
		{
			ret = false;
			break;
		}
	}
	return ret;
}